package cn.gzzhome.utils

import hudson.scm.ChangeLogSet
import org.jenkinsci.plugins.workflow.support.steps.build.RunWrapper

/**
 * scm工具
 */
class ScmHelper {

    /**
     * 当前的构建
     */
    RunWrapper currentBuild

    /**
     * 上一次成功的build
     */
    RunWrapper lastSuccessBuild

    /**
     * 当前变更过的文件
     */
    def changeFiles = [] as HashSet<String>

    /**
     * 之前变更过的文件
     */
    def preChangeFiles = [] as HashSet<String>

    /**
     * 重新初始化更新列表
     */
    def initChangeList(RunWrapper currentBuild) {
        //设置当前构建
        this.currentBuild = currentBuild
        //确认上一次成功的构建
        lastSuccessBuild = currentBuild.previousBuild
        while (lastSuccessBuild != null && "SUCCESS" != lastSuccessBuild.result.toUpperCase()) {
            lastSuccessBuild = lastSuccessBuild.previousBuild
        }
        //第一次就不用遍历了
        if (!this.lastSuccessBuild) {
            return
        }
        //清空变更列表
        changeFiles = [] as HashSet<String>
        preChangeFiles = [] as HashSet<String>
        RunWrapper build = currentBuild
        while (build != null && lastSuccessBuild.number != build.number) {
            def changeSets = build.changeSets
            if (build.number == this.currentBuild.number) {
                changeSets.each {
                    it.each {
                        def entity = it as ChangeLogSet.Entry
                        changeFiles += entity.affectedPaths
                    }
                }
            } else if (build.number != lastSuccessBuild.number) {
                changeSets.each {
                    it.each {
                        def entity = it as ChangeLogSet.Entry
                        preChangeFiles += entity.affectedPaths
                    }
                }
            }
            build = build.previousBuild
        }
    }

    /**
     * 判断文件当前是否发生改变
     * @param path
     * @param exclude
     * @return
     */
    def isChange(String path, exclude = []) {
        //首次必定为true
        if (!lastSuccessBuild) {
            return true
        }
        changeFiles.any {
            item -> item =~ /^$path/ && !(exclude && exclude.any { ex -> item =~ /^$ex/ })
        }
    }

    /**
     * 判断文件之前是否发生改变
     * @param path
     * @param exclude
     * @return
     */
    def hasChange(String path, exclude = []) {
        //首次必定为true
        if (!lastSuccessBuild) {
            return true
        }
        preChangeFiles.any {
            item -> item =~ /^$path/ && !(exclude && exclude.any { ex -> item =~ /^$ex/ })
        }
    }

}
